use std::fmt::Display;

use wtask_base::logs::TIME_FORMAT_TIME;

use crate::task::utils::{args::WTaskSubmitMetaType, meta::{CmdList, CmdMeta, CmdRet, TaskList, TaskMeta}};




impl Display for TaskMeta {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let args = self.args.iter().map(| (k, v) | {
            let type_doc = match &v.attrs {
                WTaskSubmitMetaType::NumberFloat(vv) => format!("Float({} - {}, unit: {})", vv.min, vv.max, vv.unit),
                WTaskSubmitMetaType::NumberInt(vv) => format!("Int({} - {}, unit: {})", vv.min, vv.max, vv.unit),
                WTaskSubmitMetaType::Datetime(vv) => format!("Datetime({} - {})", vv.min, vv.max),
                WTaskSubmitMetaType::String(vv) => format!("String(len: {} - {})", vv.min, vv.max),
                WTaskSubmitMetaType::Path(vv) => format!("Path(dir: {}, multi: {})", vv.is_dir, vv.multi),
                WTaskSubmitMetaType::Select(vv) => format!("Select(num: {} - {}, custom: {}, {:?})", vv.min, vv.max, vv.custom, vv.kv.values().collect::<Vec<_>>()),
            };
            format!(
                "{:<12}\t{:<8}\t{:<8}\t{:<8}\t{}。{}",
                k,
                v.required,
                v.name,
                v.default().unwrap_or("".to_string()),
                v.doc,
                type_doc,
            )
        }).collect::<Vec<_>>().join("\n");
        write!(
            f,
            "App: {}({})\nVersion: {}\nEnable: {}\nArgs: \nArgID\t\tRequired\tName\t\tDefault\t\tDoc\n{}\nDocument: \n{}\n\n",
            self.name,
            self.id,
            self.version,
            self.enable,
            args,
            self.doc
        )
    }
}



impl Display for TaskList {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if self.meta {
            let data = self.apps.iter().map(| v | v.to_string()).collect::<Vec<_>>().join("");
            write!(f, "{data}")
        } else {
            let lines = self.apps.iter().map(| v |{
                format!("{}\t{}\t\t{}@{}\n", v.enable, v.name, v.id, v.version)
            }).collect::<Vec<_>>().join("");
            let enables = self.apps.iter().filter(| v | v.enable).count();
            write!(f, "Task Enable: {}/{}\nEnable\tName\t\t\tID@Version\n{}", enables, self.apps.len(), lines)
        }
    }
}

impl Display for CmdMeta {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let time_done = match self.time_done {
            Some(d) => d.format(TIME_FORMAT_TIME).to_string(),
            None => "".to_string()  
        };
        writeln!(
            f,
            "{}\t{:?}\t{}\t{}\t{}\t{}",
            self.id,
            self.status,
            self.time_create.format(TIME_FORMAT_TIME),
            time_done,
            self.note,
            self.cmd.join(" ")
        )
    }
}



impl Display for CmdList {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let lines = self.metas.iter().map(| v | v.to_string()).collect::<Vec<String>>().join("");
        let status = if let Some(status) = &self.status {
            format!("Filtered status: {status:?}\n")
        } else {
            "".to_string()
        };
        write!(f, "{status}ID\t\t\t\t\tStatus\tTime Create       \tTime Done        \tNote        \tCmd\n{lines}")
    }
}


impl Display for CmdRet {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Exe: {}\nID: {}\nDir: {:?}", self.exe, self.id, self.dir_result)
    }
}